package com.styletransfer.mapper;

import com.styletransfer.model.User;
import org.apache.ibatis.annotations.*;

import java.util.List;

/**
 * 用户Mapper接口
 *
 * 这个接口定义了与用户表相关的数据库操作方法。
 * 使用MyBatis的注解方式，可以直接在接口方法上编写SQL语句。
 */
@Mapper
public interface UserMapper {

    /**
     * 根据ID查询用户
     *
     * @param id 用户ID
     * @return 用户对象
     */
    @Select("SELECT * FROM user WHERE id = #{id}")
    User findById(Long id);

    /**
     * 根据用户名查询用户
     *
     * @param username 用户名
     * @return 用户对象
     */
    @Select("SELECT * FROM user WHERE username = #{username}")
    User findByUsername(String username);

    /**
     * 根据邮箱查询用户
     *
     * @param email 邮箱
     * @return 用户对象
     */
    @Select("SELECT * FROM user WHERE email = #{email}")
    User findByEmail(String email);

    /**
     * 插入用户
     *
     * @param user 用户对象
     * @return 影响的行数
     */
    @Insert("INSERT INTO user(username, password, nickname, avatar, email, phone, gender, bio, createTime, updateTime, status, role) " +
            "VALUES(#{username}, #{password}, #{nickname}, #{avatar}, #{email}, #{phone}, #{gender}, #{bio}, #{createTime}, #{updateTime}, #{status}, #{role})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert(User user);

    /**
     * 更新用户
     *
     * @param user 用户对象
     * @return 影响的行数
     */
    @Update("UPDATE user SET nickname = #{nickname}, avatar = #{avatar}, email = #{email}, " +
            "phone = #{phone}, gender = #{gender}, bio = #{bio}, updateTime = #{updateTime} " +
            "WHERE id = #{id}")
    int update(User user);

    /**
     * 更新用户密码
     *
     * @param id 用户ID
     * @param password 新密码
     * @return 影响的行数
     */
    @Update("UPDATE user SET password = #{password}, updateTime = NOW() WHERE id = #{id}")
    int updatePassword(@Param("id") Long id, @Param("password") String password);

    /**
     * 更新用户状态
     *
     * @param id 用户ID
     * @param status 新状态
     * @return 影响的行数
     */
    @Update("UPDATE user SET status = #{status}, updateTime = NOW() WHERE id = #{id}")
    int updateStatus(@Param("id") Long id, @Param("status") Integer status);

    /**
     * 查询所有用户
     *
     * @return 用户列表
     */
    @Select("SELECT * FROM user ORDER BY id DESC")
    List<User> findAll();

    /**
     * 分页查询用户
     *
     * @param offset 偏移量
     * @param limit 限制数
     * @return 用户列表
     */
    @Select("SELECT * FROM user ORDER BY id DESC LIMIT #{offset}, #{limit}")
    List<User> findByPage(@Param("offset") Integer offset, @Param("limit") Integer limit);

    /**
     * 统计用户总数
     *
     * @return 用户总数
     */
    @Select("SELECT COUNT(*) FROM user")
    Long count();

    /**
     * 搜索用户
     *
     * @param keyword 关键词
     * @return 用户列表
     */
    @Select("SELECT * FROM user WHERE username LIKE CONCAT('%', #{keyword}, '%') " +
            "OR nickname LIKE CONCAT('%', #{keyword}, '%') " +
            "OR email LIKE CONCAT('%', #{keyword}, '%') " +
            "ORDER BY id DESC")
    List<User> search(String keyword);

    /**
     * 查询用户的关注者列表（粉丝）
     *
     * @param userId 用户ID
     * @return 关注者ID列表
     */
    @Select("SELECT follow_id FROM user_follow WHERE following_id = #{userId}")
    List<Long> findFollowersByUserId(Long userId);


    /**
     * 查询用户关注的用户列表
     *
     * @param userId 用户ID
     * @return 被关注用户ID列表
     */
    @Select("SELECT following_id FROM user_follow WHERE follow_id = #{userId}")
    List<Long> findFollowingByUserId(Long userId);

    /**
     * 添加关注关系
     *
     * @param userId 关注者ID
     * @param followUserId 被关注者ID
     * @return 影响的行数
     */
    @Insert("INSERT INTO user_follow(following_id, follow_id) VALUES(#{userId}, #{followUserId})")
    int follow(@Param("userId") Long userId, @Param("followUserId") Long followUserId);

    /**
     * 取消关注关系
     *
     * @param userId 关注者ID
     * @param followUserId 被关注者ID
     * @return 影响的行数
     */
    @Delete("DELETE FROM user_follow WHERE following_id = #{userId} AND follow_id = #{followUserId}")
    int unfollow(@Param("userId") Long userId, @Param("followUserId") Long followUserId);

    /**
     * 检查是否已关注
     *
     * @param userId 关注者ID
     * @param followUserId 被关注者ID
     * @return 是否已关注
     */
    @Select("SELECT COUNT(*) FROM user_follow WHERE following_id = #{userId} AND follow_id = #{followUserId}")
    boolean isFollowing(@Param("userId") Long userId, @Param("followUserId") Long followUserId);

    /**
     * 添加关注关系
     *
     * @param followerId 关注者ID
     * @param followingId 被关注者ID
     * @return 影响的行数
     */
    @Insert("INSERT INTO user_follow(follow_id, following_id, create_time) VALUES(#{followerId}, #{followingId}, NOW())")
    int addFollowing(@Param("followerId") Long followerId, @Param("followingId") Long followingId);

    /**
     * 移除关注关系
     *
     * @param followerId 关注者ID
     * @param followingId 被关注者ID
     * @return 影响的行数
     */
    @Delete("DELETE FROM user_follow WHERE follow_id = #{followerId} AND following_id = #{followingId}")
    int removeFollowing(@Param("followerId") Long followerId, @Param("followingId") Long followingId);

    /**
     * 检查是否已关注
     *
     * @param followerId 关注者ID
     * @param followingId 被关注者ID
     * @return 是否已关注
     */
    @Select("SELECT COUNT(*) FROM user_follow WHERE follow_id = #{followerId} AND following_id = #{followingId}")
    boolean checkFollowing(@Param("followerId") Long followerId, @Param("followingId") Long followingId);

    /**
     * 获取用户的关注列表
     *
     * @param userId 用户ID
     * @return 关注的用户列表
     */
    @Select("SELECT u.* FROM user u " +
            "INNER JOIN user_follow uf ON u.id = uf.following_id " +
            "WHERE uf.follow_id = #{userId} " +
            "ORDER BY uf.create_time DESC")

    List<User> getFollowing(@Param("userId") Long userId);

    /**
     * 获取用户的粉丝列表
     *
     * @param userId 用户ID
     * @return 粉丝用户列表
     */
    @Select("SELECT u.* FROM user u " +
            "INNER JOIN user_follow uf ON u.id = uf.follow_id " +
            "WHERE uf.following_id = #{userId} " +
            "ORDER BY uf.create_time DESC")
    List<User> getFollowers(@Param("userId") Long userId);
}
